﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;

using DotNetNuke.Entities.Tabs;
using iFinity.DNN.Modules.UrlMaster;
using iFinity.DNN.Modules.UrlMaster.Entities;
using iFinity.PropertyAgent.ModuleFriendlyUrlProvider.Entities;
namespace iFinity.PropertyAgent.ModuleFriendlyUrlProvider.UI
{
    /// <summary>
    /// This is the code-behind for the Settings.ascx control.  This inherits from the standard .NET UserControl, but also implements the ModuleProvider specific IProviderSettings.
    /// This control will be loaded by the Portal Urls page.  It is optional for module providers, but allows users to control module settings via the interface, rather than 
    /// having to set options via web.config settings.  The writing / reading of the items from the configuration file is handled by the Url Master module, and doesn't need to 
    /// be implemented.
    /// </summary>
    public partial class Settings : System.Web.UI.UserControl, IProviderSettings
    {
        private int _portalId;
        #region controls
        protected Label lblHeader;
        protected Label lblSettings;
        protected TextBox txtStartingPropertyId;
        protected CheckBox chkRedirectOldUrls;
        protected Repeater rptTabs;

        protected Dictionary<string, string> _providerSettings;

        protected string _customFieldIdsText;
        protected string _articleUrlSourceText;
        protected string _categoryUrlStyleText;
        protected string _propertyTypeUrlSourceText;
        protected string _propertyTypeUrlsStyleText;
        protected string _noDnnPagePathText;
        protected int _noDnnPagePathTabId;
        protected string _needTabSpecifiedText;

        
        #endregion
        #region Web Form Designer Generated Code
        //[System.Diagnostics.DebuggerStepThrough]
        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }

        /// <summary>
        ///		Required method for Designer support - do not modify
        ///		the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.Load += new System.EventHandler(this.Page_Load);
            rptTabs.ItemDataBound += new RepeaterItemEventHandler(rptTabs_ItemDataBound);
        }

        private void rptTabs_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            TabToScreen(e.Item);
        }
        
        #endregion
        #region events code
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                //note page load runs after LoadSettings(); because of dynamic control loading
                
                
                //now get the javascript in
                ScriptController.InjectjQueryLibary(this.Page, true, true);
                //module-specific jquery code
                ScriptController.InjectJsLibrary(this.Page, "pap", this.ControlPath + "/js/pap.js", true, ScriptController.ScriptInjectOrder.e_Default);
                //and get the css file in
                ScriptController.InjectCssReference(this.Page, "pap_css", this.ControlPath + "/PropertyAgentprovider.css", true, ScriptController.CssInjectOrder.f_Last);
                //and put in a pre-dnn 6 ui script plus the jquery tabs library
                string preDnn6CssFile = this.ControlPath + "/ui-tabs.css";
                ScriptController.InjectjQueryTabsCss(this.Page, preDnn6CssFile, null);
            }
            catch (Exception ex)
            {
                DotNetNuke.Services.Exceptions.Exceptions.ProcessModuleLoadException(this, ex);
            }
        }

        protected void ddlSelTab_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }
        #endregion
        #region content methods
        private void LocalizeControls()
        {
            lblHeader.Text = UIController.GetResourceString(LocalResourceFile, "Header.Text", "Property Agent Friendly Url Provider Settings");
            
            _customFieldIdsText = UIController.GetResourceString(LocalResourceFile, "CustomFieldIds.Text", "Selected Property Agent Fields to use in Url");
            _propertyTypeUrlsStyleText = UIController.GetResourceString(LocalResourceFile, "PropertyTypeUrlStyle.Text", "Style of Property Type Url");
            _propertyTypeUrlSourceText = UIController.GetResourceString(LocalResourceFile, "PropertyTypeUrlSource.Text", "Source of Property Type Url");
            _noDnnPagePathText = UIController.GetResourceString(LocalResourceFile, "NoDnnPagePath.Text", "Don't show Page name for Urls on this page");
            _needTabSpecifiedText = UIController.GetResourceString(LocalResourceFile, "NeedTabSpecified.Text", "Cannot set 'No Path' value for All Tabs");
        }
        #endregion
        #region IProviderSettings Members
        /// <summary>
        /// LoadSettings is called when the module control is first loaded onto the page
        /// </summary>
        /// <remarks>
        /// This method shoudl read all the custom properties of the provider and set the controls
        /// of the page to reflect the current settings of the provider.
        /// </remarks>
        /// <param name="provider"></param>
        public void LoadSettings(iFinity.DNN.Modules.UrlMaster.ModuleFriendlyUrlProvider provider)
        {
            //build list of controls
            if (!IsPostBack)
                LocalizeControls();
            //take all the values from the provider and show on page
            //check type safety before cast
            if (provider.GetType() == typeof(PropertyAgentModuleProvider))
            {
                PropertyAgentModuleProvider moduleProvider = (PropertyAgentModuleProvider)provider;

                _providerSettings = provider.GetProviderPortalSettings();
                _noDnnPagePathTabId = moduleProvider.NoDnnPagePathTabId;

                List<int> tabIds = new List<int>();
                if (provider.TabIds.Count > 0)
                {
                    tabIds.AddRange(provider.TabIds);
                }
                else
                    if (provider.AllTabs)
                        tabIds.Add(-1);
                //bind to tab repeater
                rptTabs.DataSource = tabIds;
                rptTabs.DataBind();
                //Starting article id
                txtStartingPropertyId.Text = moduleProvider.StartingPropertyId.ToString();
                chkRedirectOldUrls.Checked = moduleProvider.RedirectUrls;
                
            }
        }

        private void TabToScreen(RepeaterItem item)
        {
            TabController tc = new TabController();
            int tabId = (int)item.DataItem;
            string tabName = "";
            if (tabId > -1)
            {
                TabInfo tab = tc.GetTab(tabId);
                tabName = tab.TabName;
            }
            else
            {
                tabName = UIController.GetResourceString(this.LocalResourceFile, "AllTabsName.Text", "All Tabs");
            }
            Label lblPageName = (Label)item.FindControl("lblPageName");
            lblPageName.Text = tabName;

            //now get the individual settings
            Hashtable customFieldIds = TabUrlOptions.GetHashTableFromSetting(_providerSettings["customFieldIds"]);
            Hashtable propertyTypeSource = TabUrlOptions.GetHashTableFromSetting(_providerSettings["propertyTypeSource"]);
            Hashtable propertyTypeStyles = TabUrlOptions.GetHashTableFromSetting(_providerSettings["propertyTypeStyle"]);
            //build options from lists
            TabUrlOptions tabOptions = new TabUrlOptions(tabId, -1, customFieldIds, propertyTypeSource, propertyTypeStyles );
            //now get controls
            HiddenField hdnTabId = (HiddenField)item.FindControl("hdnTabId");
            hdnTabId.Value = tabId.ToString();
            DropDownList ddlPropertyTypeUrlStyle = (DropDownList)item.FindControl("ddlPropertyTypeUrlStyle");
            ListBox ddlCustomFieldId = (ListBox)item.FindControl("ddlCustomFieldId");
            DropDownList ddlPropertyTypeUrlSource = (DropDownList)item.FindControl("ddlPropertyTypeUrlSource");
            CheckBox  chkNoDnnPagePath = (CheckBox)item.FindControl("chkNoDnnPagePath");

            //get list of custom fields for Property Agents
            BuildCustomFieldList(ddlCustomFieldId, tabOptions.CustomFieldIds, tabId);
            BuildDropDownList(ddlPropertyTypeUrlStyle, tabOptions.PropertyTypeStyle, typeof(PropertyTypeUrlStyle));
            BuildDropDownList(ddlPropertyTypeUrlSource, tabOptions.PropertyTypeSource, typeof(PropertyTypeUrlSource));

            Label lblCustomFieldIds = (Label)item.FindControl("lblCustomFieldIds");
            Label lblPropertyTypeUrlStyle = (Label)item.FindControl("lblPropertyTypeUrlStyle");
            Label lblPropertyTypeUrlSource = (Label)item.FindControl("lblPropertyTypeUrlSource");
            Label lblNoDnnPagePath = (Label)item.FindControl("lblNoDnnPagePath");
            if (tabId > -1)
            {
                chkNoDnnPagePath.Checked = (_noDnnPagePathTabId == tabId);
                lblNoDnnPagePath.Text = _noDnnPagePathText;
            }
            else
            {
                chkNoDnnPagePath.Visible = false;
                lblNoDnnPagePath.Text = _needTabSpecifiedText;
            }
            lblCustomFieldIds.Text = _customFieldIdsText;
            lblPropertyTypeUrlStyle.Text = _propertyTypeUrlsStyleText;
            lblPropertyTypeUrlSource.Text = _propertyTypeUrlSourceText;
        }

        private void BuildCustomFieldList(ListControl lstCustomFields, List<string> selectedCustomFieldIds, int tabId)
        {
            lstCustomFields.Items.Clear();
            Dictionary<string, string> allCustomFields = Data.DataProvider.Instance().GetPropertyAgentCustomFields(tabId);
            foreach (string fieldId in allCustomFields.Keys)
            {
                ListItem li = new ListItem();
                li.Text = allCustomFields[fieldId];
                li.Value = fieldId;
                if (selectedCustomFieldIds.Contains(fieldId))
                    li.Selected = true;
                else
                    li.Selected = false;
                lstCustomFields.Items.Add(li);
            }
        }

        private void BuildDropDownList(DropDownList ddlList, Enum setValue, Type enumType)
        {
            //loop iteration and build drop down list
            foreach (string name in Enum.GetNames(enumType))
            {
                string fullName = UIController.GetResourceString(LocalResourceFile, name + ".Text", name);
                ListItem item = new ListItem(fullName, name);
                if (name == setValue.ToString())
                    item.Selected = true;
                ddlList.Items.Add(item);
           }
        }


        /// <summary>
        /// UpdateSettings is called when the 'update' button is clicked on the interface.
        /// This should take any values from the page, and set the individual properties on the 
        /// instance of the module provider.
        /// </summary>
        /// <param name="provider"></param>
        public void UpdateSettings(iFinity.DNN.Modules.UrlMaster.ModuleFriendlyUrlProvider provider)
        {
            //check type safety before cast
            if (provider.GetType() == typeof(PropertyAgentModuleProvider))
            {
                //take values from the page and set values on provider    
                PropertyAgentModuleProvider moduleProvider = (PropertyAgentModuleProvider)provider;
                _providerSettings = provider.GetProviderPortalSettings();

                //starting propertyId
                int startingPropertyId = -1;
                if (int.TryParse(txtStartingPropertyId.Text, out startingPropertyId))
                {
                    if (startingPropertyId > -1)
                        moduleProvider.StartingPropertyId = startingPropertyId;
                }
                moduleProvider.RedirectUrls = chkRedirectOldUrls.Checked;

                //now get the individual settings from the provider, as they are now
                Hashtable customFieldIds = TabUrlOptions.GetHashTableFromSetting(_providerSettings["customFieldIds"]);
                Hashtable propertyTypeSource = TabUrlOptions.GetHashTableFromSetting(_providerSettings["propertyTypeSource"]);
                Hashtable propertyTypeStyles = TabUrlOptions.GetHashTableFromSetting(_providerSettings["propertyTypeStyle"]);

                
                //build a super-list of hashtables, where there is an entry for each setting
                Hashtable allHashtables = new Hashtable();
                allHashtables.Add("customFieldIds", customFieldIds);
                allHashtables.Add("propertyTypeSource", propertyTypeSource);
                allHashtables.Add("propertyTypeStyles", propertyTypeStyles);
                
                //in case there is any leftover settings from tabs that have been removed.
                RemoveInactiveTabIds(provider.TabIds, provider.AllTabs, allHashtables);
                //get the valeus for each tab
                foreach (RepeaterItem item in rptTabs.Items)
                {
                    TabFromScreen(moduleProvider, item, allHashtables);
                }
                
                //now feed back the hashtables back into the actual attributes for the provider
                SetProviderProperty(moduleProvider, allHashtables, "CustomFieldIds", "customFieldIds");
                SetProviderProperty(moduleProvider, allHashtables, "PropertyTypeSource", "propertyTypeSource");
                SetProviderProperty(moduleProvider, allHashtables, "PropertyTypeStyles", "propertyTypeStyles");
                
            }

        }

        private void RemoveInactiveTabIds(List<int> activeTabIds, bool allTabs, Hashtable allHashtables)
        {
            foreach (string settingName in allHashtables.Keys)
            {
                //get the setting hashtable
                Hashtable settingTable = (Hashtable)allHashtables[settingName];
                List<string> inactiveTabs = new List<string>();
                //walk through the list of tabs in the settings, and see if they are in the active list
                foreach (string tabIdRaw in settingTable.Keys)
                {
                    int tabId = 0;
                    if (int.TryParse(tabIdRaw, out tabId))
                    {
                        if (activeTabIds.Contains(tabId) == false)//this tab isn't in the list of active tabs
                            inactiveTabs.Add(tabIdRaw);
                    }
                }
                //now remove the entries
                foreach (string inactiveTabId in inactiveTabs)
                {
                    settingTable.Remove(inactiveTabId);
                }
            }
        }

        private void SetProviderProperty(PropertyAgentModuleProvider moduleProvider, Hashtable allHashtables, string providerPropertyName, string attributeName)
        {
            //use reflection to get the property
            System.Reflection.PropertyInfo settingProperty = moduleProvider.GetType().GetProperty(providerPropertyName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            if (settingProperty != null && settingProperty.CanWrite)
            {
                //get hash table from list of all hashtables for all settings
                Hashtable settingHashTable = (Hashtable)allHashtables[attributeName];
                //get delimited string of all contents of setting hash table
                string settingValue = GetDelimitedString(settingHashTable, ",", ";");
                //set provider property with hashtable values
                settingProperty.SetValue(moduleProvider, settingValue, null);
            }
        }

        private string GetDelimitedString(Hashtable settingHashTable, string colDelim, string rowDelim)
        {
            string result = "";
            if (settingHashTable != null)
            {
                foreach (object key in settingHashTable.Keys)
                {
                    object value = settingHashTable[key];
                    result += key.ToString() + colDelim + value.ToString() + rowDelim;
                }
            }
            return result;
        }

        private void TabFromScreen(PropertyAgentModuleProvider provider, RepeaterItem item, Hashtable allHashTables)
        {
            if (item != null)
            {
                HiddenField hdnTabid = (HiddenField)item.FindControl("hdnTabId");
                if (hdnTabid != null)
                {
                    string tabIdStr = hdnTabid.Value;
                    //get the values from the drop downs
                    SetHashTableFromListBox(tabIdStr, item, allHashTables, "customFieldIds", "ddlCustomFieldId");
                    SetHashTableFromDropDownValue(tabIdStr, item, allHashTables, "propertyTypeStyle", "ddlPropertyTypeUrlStyle");
                    SetHashTableFromDropDownValue(tabIdStr, item, allHashTables, "propertyTypeSource", "ddlPropertyTypeUrlSource");
                    int tabIdInt = -1;
                    if (int.TryParse(tabIdStr, out tabIdInt))
                    {
                        if (tabIdInt > -1)
                        {
                            //check if tabis marked as the noDnnPagePath
                            CheckBox chkNoDnnPagePath = (CheckBox)item.FindControl("chkNoDnnPagePath");
                            if (chkNoDnnPagePath != null && chkNoDnnPagePath.Checked)
                                provider.NoDnnPagePathTabId = tabIdInt;
                            else
                                if (provider.NoDnnPagePathTabId == tabIdInt)
                                    provider.NoDnnPagePathTabId = 0;
                        }
                    }
                }
            }
        }

        private void SetHashTableFromListBox(string tabId, RepeaterItem item, Hashtable allHashTables, string attributeName, string listId)
        {
            Hashtable tabsSetting = (Hashtable)allHashTables[attributeName];
            ListBox dropDownList = (ListBox)item.FindControl(listId);
            if (tabsSetting != null)
            {
                string values = "";
                foreach (ListItem listItem in dropDownList.Items)
                {
                    if (listItem.Selected)
                    {
                        if (string.IsNullOrEmpty(values))
                            values = listItem.Value;
                        else
                            values += "|" + listItem.Value;
                    }
                    
                }
                if (tabsSetting.ContainsKey(tabId))
                    tabsSetting[tabId] = values;
                else
                    tabsSetting.Add(tabId, values);
            }
        }
        private void SetHashTableFromDropDownValue(string tabId, RepeaterItem item, Hashtable allHashTables, string attributeName, string ddlId)
        {
            Hashtable tabsSetting = (Hashtable)allHashTables[attributeName];
            DropDownList dropDownList = (DropDownList)item.FindControl(ddlId);
            if (dropDownList.SelectedIndex > -1 && tabsSetting != null)
            {
                if (tabsSetting.ContainsKey(tabId))
                    tabsSetting[tabId] = dropDownList.SelectedValue;
                else
                    tabsSetting.Add(tabId, dropDownList.SelectedValue);
            }
        }
        
        public System.Web.UI.Control Control
        {
            get { return this;  }
        }

        public string ControlPath
        {
            get { return base.TemplateSourceDirectory; }
        }

        public string ControlName
        {
            get { return "ProviderSettings";  }
        }

        public string LocalResourceFile
        {
            get { return "DesktopModules/iFinity.PropertyAgentFriendlyUrlProvider/App_LocalResources/Settings.ascx.resx"; }
        }
        public int PortalId
        {
            get { return _portalId; }
            set { _portalId = value; }
        }

        #endregion

    }
}
